﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace ParameterManagementSystem
{
    public partial class FileGeneratorUserControl : UserControl
    {
        public FileGeneratorUserControl(ref Dictionary<string, XmlFile> xmlFilesList,
            ref ListBox listBoxXmlFiles)
        {
            variedParameters = new Dictionary<string, VariedParameter>();
            InitializeComponent();
            clearLabels();
            xmlFilesListReference = xmlFilesList;
            listBoxXmlFilesReference = listBoxXmlFiles;
            this.ModifiyInicatorCheckBox.Enabled = false;
            this.ClearCurrentButton.Enabled = false;
            this.ClearAllButton.Enabled = false;
            this.GenerateButton.Enabled = false;
        }

        private Dictionary<string, XmlFile> xmlFilesListReference;
        private ListBox listBoxXmlFilesReference;
        private XmlFile activeXmlFile;
        private XmlNode activeXmlNode;
        private int activeGroupId;
        private int activeParamId;
        private Dictionary<string, VariedParameter> variedParameters;

        public void recreateFileTree()
        {
            variedParameters.Clear();
            clearLabels();
            this.FileTreeView.Nodes.Clear();
            string activeXMLFileName;
            activeXMLFileName = listBoxXmlFilesReference.SelectedItem.ToString();
            activeXmlFile = xmlFilesListReference[activeXMLFileName];
            activeXmlFile.createFileTree(this.FileTreeView);
        }

        public void clearFileTree()
        {
            this.FileTreeView.Nodes.Clear();
            clearLabels();
            variedParameters.Clear();
        }

        private void fillLabels()
        {
            object raw_tree_tag;
            int int_tag;
            int[] int_array_tag;
            XmlNode current_element;
            string current_key;
            if (variedParameters.Count == 0)
            {
                ClearAllButton.Enabled = false;
                GenerateButton.Enabled = false;
            }
            else
            {
                ClearAllButton.Enabled = true;
                GenerateButton.Enabled = true;
            }

            raw_tree_tag = this.FileTreeView.SelectedNode.Tag;
            if (raw_tree_tag.ToString() == "-1")
            {
                clearLabels();
            }
            else if(raw_tree_tag is Array)
            {
                this.EditButton.Enabled = true;
                int_array_tag = (int[])raw_tree_tag;
                current_element = activeXmlFile.get_param(int_array_tag[0], int_array_tag[1]);
                this.AttributeNameLabel.Text = ((XmlElement)current_element).GetAttribute("NAME");
                this.AttributeHintLabel.Text = ((XmlElement)current_element).GetAttribute("HINT");
                this.AttributeTypeLabel.Text = ((XmlElement)current_element).GetAttribute("TYPE");
                this.AttributeValueLabel.Text = ((XmlElement)current_element).GetAttribute("VALUE");
                this.AttributeLevelLabel.Text = ((XmlElement)current_element).GetAttribute("LEVEL");

                activeGroupId = int_array_tag[0];
                activeParamId = int_array_tag[1];
                activeXmlNode = current_element;

                current_key = activeGroupId.ToString() + "_" + activeParamId.ToString();
                if (variedParameters.ContainsKey(current_key))
                {
                    this.ModifiyInicatorCheckBox.Checked = true;
                    this.ClearCurrentButton.Enabled = true;
                    this.GenerateButton.Enabled = true;
                }
                else
                {
                    this.ModifiyInicatorCheckBox.Checked = false;
                    this.ClearCurrentButton.Enabled = false;
                    if (variedParameters.Count == 0)
                    {
                        this.ClearAllButton.Enabled = false;
                        this.GenerateButton.Enabled = false;
                    }
                    else
                    {
                        ClearAllButton.Enabled = true;
                        GenerateButton.Enabled = true;
                    }
                }
            }
            else
            {
                this.EditButton.Enabled = false;
                int_tag = (int)raw_tree_tag;
                current_element = activeXmlFile.get_group(int_tag);
                this.AttributeNameLabel.Text = ((XmlElement)current_element).GetAttribute("NAME");
                this.AttributeHintLabel.Text = ((XmlElement)current_element).GetAttribute("HINT");
                this.AttributeTypeLabel.Text = "";
                this.AttributeValueLabel.Text = "";
                this.AttributeLevelLabel.Text = "";
                this.ModifiyInicatorCheckBox.Checked = false;
                this.ClearCurrentButton.Enabled = false;
                if (variedParameters.Count == 0)
                {
                    this.ClearAllButton.Enabled = false;
                    this.GenerateButton.Enabled = false;
                }
                else
                {
                    ClearAllButton.Enabled = true;
                    GenerateButton.Enabled = true;
                }
            }
        }

        private void clearLabels()
        {
            this.EditButton.Enabled = false;
            this.AttributeNameLabel.Text = "";
            this.AttributeHintLabel.Text = "";
            this.AttributeTypeLabel.Text = "";
            this.AttributeValueLabel.Text = "";
            this.AttributeLevelLabel.Text = "";
            this.ModifiyInicatorCheckBox.Checked = false;
            this.ClearCurrentButton.Enabled = false;
            if (variedParameters.Count == 0)
            {
                this.ClearAllButton.Enabled = false;
                this.GenerateButton.Enabled = false;
            }
            else
            {
                ClearAllButton.Enabled = true;
                GenerateButton.Enabled = true;
            }
        }

        private void FileTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            fillLabels();
        }

        private void EditButton_Click(object sender, EventArgs e)
        {
            string current_key;
            bool varied = this.ModifiyInicatorCheckBox.Checked;

            using (VaryParameterForm VaryDialog = new VaryParameterForm(activeXmlNode, activeGroupId,
                activeParamId, varied, ref variedParameters))
            {
                VaryDialog.ShowDialog();
            }
            current_key = activeGroupId.ToString() + "_" + activeParamId.ToString();
            if (variedParameters.ContainsKey(current_key))
            {
                this.ModifiyInicatorCheckBox.Checked = true;
                this.ClearAllButton.Enabled = true;
                this.ClearCurrentButton.Enabled = true;
                this.GenerateButton.Enabled = true;
            }
            else
            {
                this.ModifiyInicatorCheckBox.Checked = false;
                this.ClearCurrentButton.Enabled = false;
                if (variedParameters.Count == 0)
                {
                    this.ClearAllButton.Enabled = false;
                    this.GenerateButton.Enabled = false;
                }
                else
                {
                    ClearAllButton.Enabled = true;
                    GenerateButton.Enabled = true;
                }
            }
        }

        private void create_variation(string name, List<VariedParameter> unvaried_yet,
            ref XmlFile xmlPattern, ref int name_var_cnt)
        {
            int list_counter = 0;
            string local_name = name;
            List<VariedParameter> locally_unvaried, locally_varied;
            XmlFile xmlReference = xmlPattern;
            XmlFile xmlCopy;

            locally_unvaried = new List<VariedParameter>(unvaried_yet);

            while(locally_unvaried.Count > 0)
            {
                foreach (string value in locally_unvaried[list_counter].values)
                {
                    xmlReference.set_param(locally_unvaried[list_counter].group_id,
                        locally_unvaried[list_counter].param_id, value);

                    if (locally_unvaried.Count > 1)
                    {
                        locally_varied = new List<VariedParameter>(locally_unvaried);
                        locally_varied.RemoveAt(list_counter);
                        create_variation(local_name, locally_varied, ref xmlReference,
                            ref name_var_cnt);
                    }
                    else
                    {
                        xmlCopy = new XmlFile();
                        xmlCopy.name = local_name + "_" + name_var_cnt.ToString();
//                        while (xmlFilesListReference.ContainsKey(xmlCopy.name))
//                        {
//                            xmlCopy.name += "_";
//                        }
                        xmlCopy.tag = xmlReference.tag;
                        xmlCopy.timeStamp = DateTime.Now;
                        xmlCopy.content = xmlReference.content;

                        xmlFilesListReference.Add(xmlCopy.name, xmlCopy);
                        listBoxXmlFilesReference.Items.Add(xmlCopy.name);
                        name_var_cnt++;
                    }
                }
                locally_unvaried.RemoveAt(list_counter);
                list_counter++;
                return;
            }
        }

        private void generate_variations()
        {
            string main_name;
            int name_var_cnt = 0;
            XmlFile xmlReference = new XmlFile();
            List<VariedParameter> varied_parameters_list;
            

            main_name = this.NewNameTextBox.Text;
            if (main_name != "")
            {
                if((xmlFilesListReference.ContainsKey(main_name)) ||
                    (xmlFilesListReference.ContainsKey(main_name+"_0")))
                {
                    MessageBox.Show("File with provided name already exists, please enter new name",
                    "Invalid name",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                    return;
                }
                else
                {
                    xmlReference.name = activeXmlFile.name;
                    xmlReference.tag = activeXmlFile.tag;
                    xmlReference.timeStamp = activeXmlFile.timeStamp;
                    xmlReference.content = activeXmlFile.content;

                    varied_parameters_list = new List<VariedParameter>(variedParameters.Values);
                    create_variation(main_name, varied_parameters_list, ref xmlReference,
                        ref name_var_cnt);
                }
            }
        }

        private void GenerateButton_Click(object sender, EventArgs e)
        {
            if (this.NewNameTextBox.Text != "")
            {
                generate_variations();
            }
            else
            {
                MessageBox.Show("No file name provided, variatons cannot be generated",
                "No file name",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);
            }
        }

        private void ClearAllButton_Click(object sender, EventArgs e)
        {
            variedParameters.Clear();
            this.ModifiyInicatorCheckBox.Checked = false;
            this.ClearAllButton.Enabled = false;
            this.ClearCurrentButton.Enabled = false;
            this.GenerateButton.Enabled = false;
        }

        private void ClearCurrentButton_Click(object sender, EventArgs e)
        {
            string current_key;
            current_key = activeGroupId.ToString() + "_" + activeParamId.ToString();
            variedParameters.Remove(current_key);
            this.ModifiyInicatorCheckBox.Checked = false;
            this.ClearCurrentButton.Enabled = false;
            if (variedParameters.Count == 0)
            {
                this.ClearAllButton.Enabled = false;
                this.GenerateButton.Enabled = false;
            }
            else
            {
                ClearAllButton.Enabled = true;
                GenerateButton.Enabled = true;
            }
        }
    }
}
